package  com.zhb.cloud.utils;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Hex;

/**
 * @ClassName: RSAStrategy
 * @Description: rsa 非对称 加密方式
 * @author: zhb zhb1316783262@163.com
 * @date: 2018年3月13日 下午2:39:05
 */
public class RsaUtil {
	/**
	 * 公钥
	 */
	private static RSAPublicKey rsaPublicKey;
	/**
	 * 私钥
	 */
	private static RSAPrivateKey rsaPrivateKey;
	/**
	 * 签名对象
	 */
	private static Signature signature = null;
	/**
	 * key生成工厂
	 */
	private static KeyFactory keyFactory = null;

	/**
	 * @Description: 初始化生成公钥和私钥对
	 * @author: zhb zhb1316783262@163.com
	 * @date: 2018年3月13日 下午3:13:22
	 */
	static {
		try {
			// 初始化密钥
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
			keyPairGenerator.initialize(512);
			KeyPair keyPair = keyPairGenerator.generateKeyPair();
			// 生成公钥
			rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
			// 生成私钥
			rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
			// 签名
			signature = Signature.getInstance("MD5withRSA");
			keyFactory = KeyFactory.getInstance("RSA");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

	}

	/**
	 * @Description:公钥加密 私钥解密
	 * @author: zhb zhb1316783262@163.com
	 * @date: 2018年3月13日 下午3:08:58
	 * @param src
	 * @return
	 */
	public static String encodePubKey(String src) {
		try {
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			byte[] resultBytes = cipher.doFinal(src.getBytes());
			return Hex.encodeHexString(resultBytes);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @Description: 私钥加密
	 * @author: zhb zhb1316783262@163.com
	 * @date: 2018年3月13日 下午2:38:55
	 * @param src
	 * @return
	 */
	public static String encodePriKey(String src) {
		try {
			// 私钥加密 公钥解密
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE, privateKey);
			byte[] resultBytes = cipher.doFinal(src.getBytes());
			return Hex.encodeHexString(resultBytes);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @Description: 私钥加密 公钥解密
	 * @author: zhb zhb1316783262@163.com
	 * @date: 2018年3月13日 下午3:11:38
	 * @param src
	 * @return
	 */
	public static String decodePubKey(String src) {
		try {
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, publicKey);
			byte[] resultBytes = cipher.doFinal(Hex.decodeHex(src.toCharArray()));
			return new String(resultBytes);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @Description: 私钥解密 公钥加密
	 * @author: zhb zhb1316783262@163.com
	 * @date: 2018年3月13日 下午3:12:03
	 * @param src
	 * @return
	 */
	public static String decodePriKey(String src) {
		try {
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			Cipher cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, privateKey);
			byte[] resultBytes = cipher.doFinal(Hex.decodeHex(src.toCharArray()));
			return new String(resultBytes);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @Description: 生成签名
	 * @author: zhb zhb1316783262@163.com
	 * @date: 2018年3月13日 下午3:34:41
	 * @param src
	 * @return
	 */
	public static byte[] generateSign(String src) {
		try {
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
			PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			signature.initSign(privateKey);
			signature.update(src.getBytes());
			// 生成签名bytes
			return signature.sign();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @Description: 数字签名校验
	 * @author: zhb zhb1316783262@163.com
	 * @date: 2018年3月13日 下午3:28:36
	 * @param src
	 * @return
	 */
	public static boolean verifySign(String src, byte[] sign) {
		try {
			X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
			PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
			signature.initVerify(publicKey);
			signature.update(src.getBytes());
			return signature.verify(sign);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
}